home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / Add-ons / VideoShop Plug-In Kit 1.0 / SampleXsn.c < prev    next >
Text File  |  1992-05-06  |  10KB  |  427 lines

  1. /*
  2.  
  3.     SampleXsn.c
  4.     
  5.     Sample transition effect for VideoShop
  6.     
  7. */
  8.  
  9. /*    Includes    */
  10.  
  11. #include <Types.h>
  12. #include <Memory.h>
  13. #include <Resources.h>
  14. #include <QuickDraw.h>
  15. #include <QDOffscreen.h>
  16. #include <Dialogs.h>
  17. #include <OSUtils.h>
  18. #include <Packages.h>
  19. #include <Errors.h>
  20. #include <ToolUtils.h>
  21. #include <SysEqu.h>
  22. #include <Math.h>
  23. #include <GestaltEqu.h>
  24. #include "DiVATransition.h"
  25.  
  26. /*    Type definitions    */
  27.  
  28. typedef struct WipeParams {
  29.     unsigned short angle;
  30. } WipeParams, *WipeParamPtr, **WipeParamHandle;
  31.  
  32. /*    Konstants    */
  33.  
  34. #define dialogID    16001
  35. #define defaultItem    3
  36. #define leftToRightItem 5
  37. #define topToBottomItem 6
  38. #define rightToLeftItem 7
  39. #define bottomToTopItem 8
  40. #define dividerItem    10
  41.  
  42. /*    Prototypes    */
  43.  
  44. XsnErr DoParameters (XsitionParamPtr params);
  45.  
  46. XsnErr DoProcessFrame (XsitionParamPtr params, short transitionIntensity,
  47.     short maxTransitionIntensity);
  48.  
  49. pascal XsnErr XsnEntryPoint (short selector, XsitionParamPtr params, long *data,
  50.     short transitionIntensity, short maxTransitionIntensity)
  51. /*
  52.     The transition entry point and dispatcher routine. Calls the appropriate
  53.     subroutine based on the selector passed.
  54. */
  55. {
  56. #pragma unused(data)
  57.     switch (selector) {
  58.         case XSParameters:
  59.             return (DoParameters (params));
  60.             break;
  61.         case XSPrepare:
  62.         case XSStart:
  63.         case XSFinish:
  64.             return (noErr);
  65.             break;
  66.         case XSProcessFrame:
  67.             return (DoProcessFrame (params, transitionIntensity, maxTransitionIntensity));
  68.             break;
  69.         default:
  70.             return (-1);
  71.     }
  72. }
  73.  
  74. pascal Boolean DoTestAbort (ProcPtr codeAddress)
  75. /*    Inline code to call the TestAbort function    */
  76.     =     {0x205F,            //    move.l    (a7)+,a0        pop procPtr from stack
  77.          0x4E90};            //    jsr        (a0)            and call it
  78.  
  79. Boolean TestAbort (XsitionParamPtr params)
  80. {
  81.     ProcPtr address;
  82.  
  83.     address = params->abortProc;
  84.     return (DoTestAbort (address));
  85. }
  86.  
  87. pascal void DoUpdateProgress (long done, long total, ProcPtr codeAddress)
  88. /*    Inline code to call the UpdateProgress function    */
  89.     =     {0x205F,            //    move.l    (a7)+,a0        pop procPtr from stack
  90.          0x4E90};            //    jsr        (a0)            and call it
  91.  
  92. void UpdateProgress (XsitionParamPtr params, long done, long total)
  93. {
  94.     ProcPtr address;
  95.  
  96.     address = params->progressProc;
  97.     DoUpdateProgress (done, total, address);
  98. }
  99.  
  100. void CenterDialog (DialogTHndl dt)
  101. /*
  102.     Given a dialog template in dt, modify it so as to center the dialog on the
  103.     main device.
  104. */
  105. {
  106.     Rect r;
  107.     short width;
  108.     short height;
  109.     GDHandle    mainDevice;
  110.  
  111.     mainDevice = GetMainDevice();
  112.     width  = (**mainDevice).gdRect.right;
  113.     height = (**mainDevice).gdRect.bottom;
  114.  
  115.     r = (**dt).boundsRect;
  116.     OffsetRect (&r, -r.left, -r.top);
  117.     OffsetRect (&r, (width - r.right) / 2,
  118.                     (height - r.bottom - GetMBarHeight()) / 3 + GetMBarHeight());
  119.     (**dt).boundsRect = r;
  120. }
  121.  
  122. pascal void OutlineOK (DialogPtr dp, short item)
  123. /*
  124.     userItem drawing routine for outlining the default button in the dialog box
  125. */
  126. {
  127.     Rect r;
  128.     Handle h;
  129.     short itemType;
  130.  
  131.     item = ok;
  132.     GetDItem (dp, item, &itemType, &h, &r);
  133.     PenNormal ();
  134.     PenSize (3, 3);
  135.     InsetRect (&r, -4, -4);
  136.     FrameRoundRect (&r, 16, 16);
  137.     PenNormal ();
  138. }
  139.  
  140. GDHandle    GetWindowGDevice(WindowPtr w)
  141. /*
  142.     Find the deepest gdevice the window intersects. Used for determining the depth
  143.     of the screen we're drawing on (to look good on B/W displays).
  144. */
  145. {
  146.     Rect    r=w->portRect;
  147.     GrafPtr    oldPort;
  148.     GDHandle    theGD;
  149.     
  150.     GetPort (&oldPort);
  151.     SetPort (w);
  152.     LocalToGlobal((Point *)&r);
  153.     LocalToGlobal((Point *)(&(r.bottom)));
  154.     theGD = GetMaxDevice(&r);
  155.     SetPort (oldPort);
  156.     return (theGD);
  157. }
  158.  
  159. pascal void DrawLines (DialogPtr theDialog, short itemNo)
  160. /*
  161.     userItem drawing routine for dividing lines (with shadow)
  162. */
  163. {
  164.     RGBColor    oldColor,greyColor;
  165.     short    itemType;
  166.     Handle    me;
  167.     Rect    box;
  168.     
  169.     GetDItem(theDialog,itemNo,&itemType,&me,&box);
  170.     GetForeColor(&oldColor);
  171.     RGBForeColor((RGBColor*)RGBBlack);
  172.     MoveTo(box.left,box.top);
  173.     LineTo(box.right-2,box.top);
  174.     MoveTo(box.left,box.top+3);
  175.     LineTo(box.right-2,box.top+3);
  176.     if (((**((*GetWindowGDevice(theDialog))->gdPMap)).pixelSize >= 8)) {
  177.         greyColor.red = greyColor.green = greyColor.blue = 0x7777;
  178.         RGBForeColor (&greyColor);
  179.         MoveTo(box.left+1,box.top+1);
  180.         LineTo(box.right-1,box.top+1);
  181.         MoveTo(box.left+1,box.top+4);
  182.         LineTo(box.right-1,box.top+4);
  183.     }
  184.     RGBForeColor(&oldColor);
  185. }
  186.  
  187. void SetupDItems (DialogPtr dp)
  188. /*
  189.     Set up the dialog items
  190. */
  191. {
  192.     Rect r;
  193.     short    itemType;
  194.     Handle    item;
  195.     
  196.     //    default outline
  197.     GetDItem (dp, defaultItem, &itemType, &item , &r);
  198.     SetDItem (dp, defaultItem,  itemType, (Handle) &OutlineOK, &r);
  199.     
  200.     //    dividing lines
  201.     GetDItem (dp, dividerItem, &itemType, &item , &r);
  202.     SetDItem (dp, dividerItem,  itemType, (Handle) DrawLines, &r);
  203. }
  204.  
  205. /*
  206.     Macro to disable all but one dialog items in a given range. Used for managing
  207.     sets of radio buttons.
  208. */
  209. #define DisableAllButMe(i) for (j=leftToRightItem; j<=bottomToTopItem; j++) {    \
  210.     if (j==i) continue; GetDItem (dp,j,&itemType,&h,&r);    \
  211.     SetCtlValue((ControlHandle)h,0); }
  212.  
  213. void RecalcDItems (WipeParamHandle    p, DialogPtr dp)
  214. {
  215.     short    itemType,j;
  216.     Handle    h;
  217.     Rect    r;
  218.     
  219.     switch ((**p).angle) {
  220.         case 0:
  221.             DisableAllButMe(bottomToTopItem);
  222.             GetDItem (dp,bottomToTopItem,&itemType,&h,&r);
  223.             SetCtlValue ((ControlHandle)h,1);
  224.             break;
  225.         case 90:
  226.             DisableAllButMe(leftToRightItem);
  227.             GetDItem (dp,leftToRightItem,&itemType,&h,&r);
  228.             SetCtlValue ((ControlHandle)h,1);
  229.             break;
  230.         case 180:
  231.             DisableAllButMe(topToBottomItem);
  232.             GetDItem (dp,topToBottomItem,&itemType,&h,&r);
  233.             SetCtlValue ((ControlHandle)h,1);
  234.             break;
  235.         case 270:
  236.             DisableAllButMe(rightToLeftItem);
  237.             GetDItem (dp,rightToLeftItem,&itemType,&h,&r);
  238.             SetCtlValue ((ControlHandle)h,1);
  239.             break;
  240.     }
  241. }
  242.  
  243. XsnErr DoParameters (XsitionParamPtr params)
  244. /*
  245.     Prompt the user for parameters if necessary.
  246. */
  247. {
  248.     short item;
  249.     DialogPtr dp;
  250.     DialogTHndl dt;
  251.     WipeParamHandle    theParams;
  252.  
  253.     /*    If we didn't get passed a params handle, allocate and initialize it    */
  254.     if (!params->parameters) {
  255.         params->parameters = NewHandle (sizeof (WipeParams));
  256.         if (!params->parameters) return (XSErrOutOfMemory|MemError());
  257.         theParams = (WipeParamHandle) params->parameters;
  258.         (**theParams).angle = 90;
  259.     } else
  260.     /*
  261.         Otherwise, we just return. If we required specific hardware or mounds of
  262.         memory we would check here.
  263.     */
  264.         return(noErr);
  265.     
  266.     /*    Load in the dialog and center it    */
  267.     dt = (DialogTHndl) GetResource ('DLOG', dialogID);
  268.     HNoPurge ((Handle) dt);
  269.     CenterDialog (dt);
  270.  
  271.     /*    Show it    */
  272.     dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
  273.     
  274.     /*    Setup the user items and initialize all controls to initial state    */
  275.     SetupDItems (dp);
  276.     RecalcDItems (theParams, dp);
  277.     
  278.     do {
  279.         ModalDialog (nil, &item);
  280.         switch (item) {
  281.             case topToBottomItem:
  282.                 (**theParams).angle=180;
  283.                 RecalcDItems (theParams, dp);
  284.                 break;
  285.             case leftToRightItem:
  286.                 (**theParams).angle=90;
  287.                 RecalcDItems (theParams, dp);
  288.                 break;
  289.             case bottomToTopItem:
  290.                 (**theParams).angle=0;
  291.                 RecalcDItems (theParams, dp);
  292.                 break;
  293.             case rightToLeftItem:
  294.                 (**theParams).angle=270;
  295.                 RecalcDItems (theParams, dp);
  296.                 break;
  297.         }
  298.     } while (item != ok && item != cancel);
  299.  
  300.     DisposDialog (dp);
  301.     HPurge ((Handle) dt);
  302.  
  303.     if (item == cancel) {
  304.         DisposHandle ((Handle)theParams);
  305.         params->parameters = nil;
  306.         return (XSErrReported);
  307.     }
  308.     return (noErr);
  309. }
  310.  
  311. XsnErr DoProcessFrame (XsitionParamPtr params, short transitionIntensity, short maxTransitionIntensity)
  312. /*    Perform the effect    */
  313. {
  314.     PixMapHandle    srcA,srcB,dest;
  315.     GWorldFlags    pmStateA,pmStateB,pmStateDest;
  316.     unsigned char    stateA,stateB,stateDest;
  317.     Rect    r,bounds;
  318.     GWorldPtr    oldGW, destGW;
  319.     GDHandle    oldGD;
  320.     short    ySize,xSize;
  321.     short    angle;
  322.     RGBColor    oldFore,oldBack;
  323.  
  324.     if (TestAbort (params)) return (XSErrReported);
  325.     
  326.     srcA = params->srcA;
  327.     srcB = params->srcB;
  328.     destGW = params->destImage;
  329.     
  330. /*    Get the image pixmaps, dealing with pre-System 7 GetGWorldPixMap bug    */
  331.     if (*((short*)SysVersion)<0x700) {
  332.         dest = destGW->portPixMap;
  333.     } else {
  334.         dest = GetGWorldPixMap (destGW);
  335.     }
  336.     
  337.     r = (**srcA).bounds;
  338.     ySize = r.bottom - r.top;
  339.     xSize = r.right - r.left;
  340.     UpdateProgress (params,0,3);
  341.  
  342. /*    Calculate the rectangle to copy based on the wipe direction    */
  343.     angle = (**((WipeParamHandle)(params->parameters))).angle;
  344.     switch (angle) {
  345.         case 0:
  346.             SetRect (&r,0,0,xSize,ySize);
  347.             r.top = r.bottom - (transitionIntensity * xSize / maxTransitionIntensity);
  348.             break;
  349.         case 90:
  350.             SetRect (&r,0,0,xSize,ySize);
  351.             r.right = r.left + (transitionIntensity * xSize / maxTransitionIntensity);
  352.             break;
  353.         case 180:
  354.             SetRect (&r,0,0,xSize,ySize);
  355.             r.bottom = r.top + (transitionIntensity * ySize / maxTransitionIntensity);
  356.             break;
  357.         case 270:
  358.             SetRect (&r,0,0,xSize,ySize);
  359.             r.left = r.right - (transitionIntensity * xSize / maxTransitionIntensity);
  360.             break;
  361.     }
  362.     
  363.     /*    spin the beachball    */
  364.     UpdateProgress (params,1,3);
  365.     
  366. /* save offscreen pixels state and lock them down for drawing */
  367.     pmStateA = GetPixelsState(srcA);
  368.     LockPixels (srcA);
  369.     stateA = HGetState ((Handle)srcA);
  370.     MoveHHi ((Handle)srcA);
  371.     HLock ((Handle)srcA);
  372.     pmStateB = GetPixelsState(srcB);
  373.     LockPixels (srcB);
  374.     stateB = HGetState ((Handle)srcB);
  375.     MoveHHi ((Handle)srcB);
  376.     HLock ((Handle)srcB);
  377.     pmStateDest = GetPixelsState(dest);
  378.     LockPixels (dest);
  379.     stateDest = HGetState ((Handle)dest);
  380.     MoveHHi ((Handle)dest);
  381.     HLock ((Handle)dest);
  382.     
  383. /*    save drawing state    */
  384.     GetGWorld(&oldGW,&oldGD);
  385.     SetGWorld (destGW,GetGWorldDevice(destGW));
  386.     GetForeColor (&oldFore);
  387.     GetBackColor (&oldBack);
  388.     RGBForeColor ((RGBColor*)RGBBlack);
  389.     RGBBackColor ((RGBColor*)RGBWhite);
  390.     
  391.     bounds = (**srcA).bounds;
  392.     
  393. /*    copy entire first source image    */
  394.     CopyBits((BitMap*)*srcA,(BitMap*)*dest,&bounds,&bounds,srcCopy,nil);
  395.     
  396. /*    spin beachball, restoring original graphic state    */
  397.     SetGWorld (oldGW,oldGD);
  398.     UpdateProgress (params,2,3);
  399.     SetGWorld (destGW,GetGWorldDevice(destGW));
  400.     
  401. /*    wait for accelerators    */
  402.     while (!QDDone((GrafPtr)destGW));    //    Wait for accelerator.
  403.     
  404. /*    copy the piece of the second source that we calculated earlier    */
  405.     CopyBits((BitMap*)*srcB,(BitMap*)*dest,&r,&r,srcCopy,nil);
  406.     
  407. /*    wait for accelerators    */
  408.     while (!QDDone((GrafPtr)destGW));    //    Wait for accelerator.
  409.     
  410. /*    restore graphic state    */
  411.     RGBForeColor (&oldFore);
  412.     RGBBackColor (&oldBack);
  413.     
  414.     SetGWorld (oldGW,oldGD);
  415.     UpdateProgress (params,3,3);
  416.     
  417. /*    restore offscreen pixmaps' state    */
  418.     HSetState ((Handle)srcA,stateA);
  419.     SetPixelsState(srcA,pmStateA);
  420.     HSetState ((Handle)srcB,stateB);
  421.     SetPixelsState(srcB,pmStateB);
  422.     HSetState ((Handle)dest,stateDest);
  423.     SetPixelsState(dest,pmStateDest);
  424.     
  425.     return (noErr);
  426. }
  427.